package lib;
// <editor-fold defaultstate="collapsed" desc="Imports">
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
// </editor-fold>

/**
 * @file StreamSocket.java
 *
 * @version 0.1
 * @author Chris Sewell 10008342
 */
public class StreamSocket {
    // <editor-fold defaultstate="collapsed" desc="Attributes">

    Socket socket;
    OutputStream streamOut;
    OutputStreamWriter streamWriter;
    DataOutputStream dataOut;
    PrintWriter socketOut;
    InputStream streamIn;
    InputStreamReader streamReader;
    DataInputStream dataIn;
    BufferedReader socketIn;
    boolean status;
    // </editor-fold> 
    // <editor-fold defaultstate="collapsed" desc="Constructors">

    public StreamSocket(Socket socket) throws IOException {
        this.socket = socket;
        //Create all socket objects for file and string transmition 
        streamOut = socket.getOutputStream();
        streamWriter = new OutputStreamWriter(streamOut);
        dataOut = new DataOutputStream(streamOut);
        socketOut = new PrintWriter(streamWriter);

        streamIn = socket.getInputStream();
        streamReader = new InputStreamReader(streamIn);
        dataIn = new DataInputStream(streamIn);
        socketIn = new BufferedReader(streamReader);

        status = true;
    }
    // </editor-fold> 
    // <editor-fold defaultstate="collapsed" desc="Methods">

    /**
     * These abstractions hide the try catch statements and flushes required for sending/receiving data
     */
    public void sendString(String message) {//Send and flush a string
        socketOut.println(message);
        socketOut.flush();
    }

    public String recieveString() {//Receive a string
        try {
            return socketIn.readLine();
        } catch (IOException ex) {
            Logger.getLogger(StreamSocket.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public void sendBytes(byte[] data, int length) {//Send and flush a byte array
        try {
            dataOut.write(data, 0, length);
            dataOut.flush();
        } catch (IOException ex) {
            Logger.getLogger(StreamSocket.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public byte[] recieveBytes(int length) {//Receive a byte array 
        byte[] temp = new byte[length];
        try {
            dataIn.read(temp, 0, length);
        } catch (IOException ex) {
            Logger.getLogger(StreamSocket.class.getName()).log(Level.SEVERE, null, ex);
        }
        return temp;
    }

    public String displayDetail() {//Returns client socket info for server console output
        InetAddress clientAddress;
        clientAddress = socket.getInetAddress();//Hostname will not show in Windows 7 UWE
        return clientAddress.getHostName() + " " + clientAddress.getHostAddress();
    }

    public void kill() throws IOException {//Close all socket objects
        status = false;
        socket.close();

        streamOut.close();
        dataOut.close();
        streamWriter.close();
        socketOut.close();

        streamIn.close();
        dataIn.close();
        streamReader.close();
        socketIn.close();
    }
    public boolean isOpen() {
        return status;
    }
    // </editor-fold> 
}
